package com.orkasgb.framework.redis.lock;//package com.orkasgb.framework.orkasgbframework.redis.lock;
//
//import org.redisson.Redisson;
//import org.redisson.api.RLock;
//import org.springframework.stereotype.Service;
//import redis.clients.jedis.HostAndPort;
//import redis.clients.jedis.Jedis;
//
//import javax.annotation.Resource;
//
//@Service
//public class RedisDistributedLockService {
//
//	@Resource
//	Redisson redisson;
//
//	/**
//	 * Redis实现简单的分布式锁（高并发场景下依旧存在问题）
//	 * <p>
//	 * ===========================问题分析1============================
//	 * <p>
//	 * 线程1总共需要15s执行完成，处理业务花费10s，此时redis自动删除线程1的锁。线程2刚好进来，
//	 * 发现所已经被删除，获取锁，总共需要8s执行完成，比如执行到6s的时候，线程1执行结束了，开始删除锁，
//	 * 但是此时的锁是线程2的锁，也就是说，线程1在线程2还未执行完成后，删除了线程2的锁，那么导致，线程3又
//	 * 可以获得锁执行，一次类推，同样会导致超卖问题，即锁永久失效，相当于没有加锁。解决思路：1.给每个线程设置一个唯一的值，
//	 * 类似于线程id，删除锁之前判断，这个值，相当于只有自己的才能删除自己设置的锁。2.开辟一个新的线程，不断的
//	 * 延长当前线程设置的锁的超时时间。
//	 * <p>
//	 * ===========================问题分析2============================
//	 * <p>
//	 * 思索问题，因为设置锁和设置锁过期时间是分两步操作，那么不保证原子性，如果jedis.del("product_lock")不放在
//	 * finally中，那么就会发生死锁。解决思路：使用lua脚本实现原子性。
//	 */
//	public String distributedLock() {
//		Jedis jedis = null;
//		try {
//			jedis = new Jedis(HostAndPort.from("172.25.184.11:6381"));
//			long lock = jedis.setnx("product_lock", "100001");
//			jedis.expire("product_lock", 10);
//			if (lock == 0L) {
//				System.out.println("系统繁忙，请稍后再试！");
//				return "系统繁忙，请稍后再试！";
//			}
//
//			String productNum = jedis.get("product_num");
//			if (0 == Integer.parseInt(productNum)) {
//				System.out.println("秒杀活动结束，敬请期待！");
//				return "秒杀活动结束，敬请期待！";
//			}
//			jedis.decr("product_num");
//			System.out.println("恭喜你，抢到了，目前还剩 " + productNum);
//		} catch (Exception e) {
//			System.out.println("系统繁忙，请稍后再试！");
//			return "系统繁忙，请稍后再试！";
//		} finally {
//			if (jedis != null) {
//				jedis.del("product_lock");
//			}
//		}
//		System.out.println("秒杀成功了！");
//		return "秒杀成功了！";
//	}
//
//	/**
//	 * Redisson实现分布式锁
//	 *<p>
//	 * ===========================问题分析1============================
//	 * <p>
//	 * 主从架构失效问题：假如使用主从架构，如果线程1将写锁命令发送在master上，master写成功后将写成功的
//	 * 响应反馈给客户端，突然master就奔溃了，而此时，写锁命令还没有来得及同步到slave，由于redis架构的
//	 * 高可用特性，选择了一个slave作为了新的master，此时线程2获取锁，发现新的master上并没有锁，那么加锁
//	 * 成功，同样会出现超卖问题。解决思路：选择zookeeper、redis集群或者容忍这种问题。因为在分布式架构中，
//	 * CAP只能只能满足其中两种，CP或者AP。
//	 */
//	public String redissonLock() {
//		RLock productLock = redisson.getLock("product_lock");
//		try {
//			productLock.lock();
//			Jedis jedis = new Jedis(HostAndPort.from("172.25.184.11:6381"));
//			String productNum = jedis.get("product_num");
//			if (0 == Integer.parseInt(productNum)) {
//				System.out.println("秒杀活动结束，敬请期待！");
//				return "秒杀活动结束，敬请期待！";
//			}
//			jedis.decr("product_num");
//			System.out.println("恭喜你，抢到了，目前还剩 " + jedis.get("product_num"));
//		} catch (Exception e) {
//			System.out.println("系统繁忙，请稍后再试！");
//			return "系统繁忙，请稍后再试！";
//		} finally {
//			productLock.unlock();
//		}
//		System.out.println("秒杀成功了！");
//		return "秒杀成功了！";
//	}
//}
